﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Workflows.Components.Entities.Providers;

namespace Workflows.Components.Entities.Relations.DirectAssociations
{
    public class SelfReferenceAssociation : Relation
    {
        public SelfReferenceAssociation(
            EntityMetaData metaData,
            Dictionary<string, string> mappings, 
            string label) 
            : base(metaData, metaData, EntityReferenceType.SelfRef, mappings, 
            RelationshipDirection.FromEntity1ToEntity2, label)
        {
        }

        public override void PopulateFromSeed(
            Entity seed, EntityProvider srcProvider, EntityProvider refProvider,
            ref Dictionary<string, List<string>> entityConnections)
        {
            Debug.Assert(srcProvider == refProvider);

            if (entityConnections == null)
                entityConnections = new Dictionary<string, List<string>>();
            entityConnections.Clear();

            string fkAttrName = this.MappingsFromEntity1ToEntity2[this.SrcMetaData.IdAttributeName];
            List<string> fks = srcProvider.GetEntityIDsByFK(fkAttrName, seed.Id);
            entityConnections.Add(seed.Id, fks);
            this.PopulateFromSeed(seed.Id, fkAttrName, srcProvider, ref entityConnections);
        }

        private void PopulateFromSeed(string seedID, string fkAttrName,
            EntityProvider provider, ref Dictionary<string, List<string>> entityConnections)
        {
            if (entityConnections.ContainsKey(seedID))
                return;

            List<string> fks = provider.GetEntityIDsByFK(fkAttrName, seedID);
            entityConnections.Add(seedID, fks);

            List<string> fkAdded = new List<string>();
            foreach (string fk in fks)
            {
                if(!entityConnections.ContainsKey(fk))
                {
                    fkAdded.Add(fk);
                }
            }
            if(fkAdded.Count>0)
            {
                foreach (string fk in fkAdded)
                {
                    this.PopulateFromSeed(fk, fkAttrName, provider, ref entityConnections);
                }
            }
        }
    }
}
